#pragma once
#include "socket.hpp"
#include <memory>
#include <iostream>
#include <sys/wait.h>
#include <functional>
using namespace socket_module;
using service_function =std::function<void(Socket::ptr& sock,InetAddr& peer)>;
class TcpServer
{  
public:
    using ptr=std::shared_ptr<TcpServer>;
    TcpServer(uint16_t port)
    :_port(port),
    _listen_socket_ptr(std::make_unique<TcpSocket>()),
    _is_running(false)
    {
    _listen_socket_ptr->BulidTcpSocket(_port);
    }
public:
    void Start(service_function server_func)
    {
        _is_running=true;
        while (_is_running)
        {
            InetAddr client;
            auto sock=_listen_socket_ptr->Accept(client);//取得与客户端通信的socket
            if(sock==nullptr)
            {
                LOG(log_level::ERROR)<<"accept fail";
                continue;
            }
            LOG(log_level::DEBUG)<<"accept success";
            pid_t pid=fork();
            if(pid<0)
            {
                LOG(log_level::FATAL)<<"fork fail";
                exit(FORK_ERR);
            }
            else if(pid==0)
            {
                //子进程关掉不需要的文件描述符以免出现问题
                _listen_socket_ptr->Close();
                if(fork()>0)
                {
                    exit(OK);
                }
                //孙子进程变成孤儿 正常执行任务
                //。。。。。
                server_func(sock,client);
                sock->Close();
                exit(OK);
            }
            else
            {
                sock->Close();
                int id=waitpid(pid,nullptr,0);
                (void)id;
            }
        }
        _is_running=false;
    }
private:
    bool _is_running;
    uint16_t _port;
    std::unique_ptr<Socket> _listen_socket_ptr;
    service_function _server_func;
};